<?php
class Main_Auth_Adapter_DbTable implements Zend_Auth_Adapter_Interface
{
	/**
	 * @var Main_Db_Adapter_Abstract
	 */
	protected $_db;
	
	/**
	 * @var string
	 */
	protected $_tableName;
	
	/**
	 * @var string
	 */
	protected $_identityColumn;
	
	/**
	 * @var string
	 */
	protected $_credentialColumn;
	
	/**
	 * @var string
	 */
	protected $_identity;
	
	/**
	 * @var string
	 */
	protected $_credential;
	
	/**
	 * @var array
	 */  
    protected $_authenticateResultInfo = null;
    
    /**
     * @var array
     */
    protected $_resultRow = null;
	
    /**
     * @param Main_Db_Adapter_Abstract $db
     * @param string $tableName
     * @param string $identityColumn
     * @param string $credentialColumn
     * @return void
     */
	public function __construct(Main_Db_Adapter_Abstract $db, $tableName = null, $identityColumn = null, $credentialColumn = null) 
    {
    	$this->_db = $db;
    	
		if (null !== $tableName) {
            $this->setTableName($tableName);
        }

        if (null !== $identityColumn) {
            $this->setIdentityColumn($identityColumn);
        }

        if (null !== $credentialColumn) {
            $this->setCredentialColumn($credentialColumn);
        }
	}

	/**
	 * @param string $tableName
	 * @return Main_Auth_Adapter_DbTable
	 */
    public function setTableName($tableName)
    {
        $this->_tableName = $tableName;
        $this->_tableName = $this->_db->escape($this->_tableName);
        return $this;
    }
	
    /**
	 * @param string $identityColumn
	 * @return Main_Auth_Adapter_DbTable
	 */
    public function setIdentityColumn($identityColumn)
    {
        $this->_identityColumn = $identityColumn;
        $this->_identityColumn = $this->_db->escape($this->_identityColumn);
        return $this;
    }

    /**
	 * @param string $credentialColumn
	 * @return Main_Auth_Adapter_DbTable
	 */
    public function setCredentialColumn($credentialColumn)
    {
        $this->_credentialColumn = $credentialColumn;
        $this->_credentialColumn = $this->_db->escape($this->_credentialColumn);
        return $this;
    }
    
    /**
     * @param string $value
     * @return Main_Auth_Adapter_DbTable
     */
    public function setIdentity($value)
    {
        $this->_identity = $value;
        $this->_identity = $this->_db->escape($this->_identity);
        return $this;
    }
    
    /**
     * @param string $credential
     * @return Main_Auth_Adapter_DbTable
     */
    public function setCredential($credential)
    {
        $this->_credential = $credential;
        $this->_credential = $this->_db->escape($this->_credential);
        return $this;
    }
    
    /**
     * getResultRowObject() - Returns the result row as a stdClass object
     *
     * @param  string|array $returnColumns
     * @param  string|array $omitColumns
     * @return stdClass|boolean
     */
    public function getResultRowObject($returnColumns = null, $omitColumns = null)
    {
    	if (!$this->_resultRow) {
            return false;
        }

        $returnObject = new stdClass();
    	
    	if (null !== $returnColumns) {

            $availableColumns = array_keys($this->_resultRow);
            foreach ( (array) $returnColumns as $returnColumn) {
                if (in_array($returnColumn, $availableColumns)) {
                    $returnObject->{$returnColumn} = $this->_resultRow[$returnColumn];
                }
            }
            return $returnObject;

        } elseif (null !== $omitColumns) {

            $omitColumns = (array) $omitColumns;
            foreach ($this->_resultRow as $resultColumn => $resultValue) {
                if (!in_array($resultColumn, $omitColumns)) {
                    $returnObject->{$resultColumn} = $resultValue;
                }
            }
            return $returnObject;

        } else {

            foreach ($this->_resultRow as $resultColumn => $resultValue) {
                $returnObject->{$resultColumn} = $resultValue;
            }
            return $returnObject;

        }
    }
    
    /**
     * @throws Zend_Auth_Adapter_Exception
     * @return Zend_Auth_Result
     */
    public function authenticate()
    {
    	$this->_authenticateSetup();
    	$sql = $this->_authenticateCreateSql();
    	$resultIdentities = $this->_authenticateQueryResult($sql);
    	//echo $resultIdentities; exit; 	
    	
    	if (true === $resultIdentities) {
    		$this->_authenticateResultInfo['code'] = Zend_Auth_Result::SUCCESS;
        	$this->_authenticateResultInfo['messages'][] = 'Authentication successful.';
    	} else {
    		$this->_authenticateResultInfo['code'] = Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID;
            $this->_authenticateResultInfo['messages'][] = 'Supplied credential is invalid.';
    	}
    	return $this->_authenticateCreateAuthResult();
    }
    
    /**
     * @return Zend_Auth_Result
     */
	protected function _authenticateCreateAuthResult()
    {
        return new Zend_Auth_Result(
            $this->_authenticateResultInfo['code'],
            $this->_authenticateResultInfo['identity'],
            $this->_authenticateResultInfo['messages']
            );
    }
    
    /**
     * @return bool
     */
    protected function _authenticateQueryResult($sql) 
    {
    	try {
    		$res = $this->_db->fetchRow($sql);
    	} catch (Exception $e) {
    		throw new Zend_Auth_Adapter_Exception('The supplied parameters to Zend_Auth_Adapter_DbTable failed to '
                                                . 'produce a valid sql statement, please check table and column names '
                                                . 'for validity.', 0, $e);	
    	}
    	
    	if (!empty($res)) {
    		$this->_resultRow = $res;
    		//print_r($res); exit;
    		return true;
    	} else {
    		return false;
    	}
    }
    
    /**
     * @return true
     */
    protected function _authenticateSetup()
    {
    	if ( (empty($this->_tableName)) || (empty($this->_identityColumn)) 
    		 || (empty($this->_identity)) || (empty($this->_credentialColumn))
    		 || (empty($this->_credentialColumn)) 
    	) {
    		require_once 'Zend/Auth/Adapter/Exception.php';
            throw new Zend_Auth_Adapter_Exception('Authenticate adapter params are wrong');	
    	}
    	
    	$this->_authenticateResultInfo = array(
            'code'     => Zend_Auth_Result::FAILURE,
            'identity' => $this->_identity,
            'messages' => array()
        );
        
		return true;            
    }
    
    /**
     * @return sql
     */
    protected function _authenticateCreateSql()
    {
    	$sql = "
    	SELECT 
    		* 
    	FROM 
    		{$this->_tableName}
    	WHERE 
    		{$this->_identityColumn}='{$this->_identity}' AND
    		{$this->_credentialColumn}='{$this->_credential}'
    	";
		return $sql;    		
    }
}
